home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Personal Computer World 2009 February
/
PCWFEB09.iso
/
Software
/
Resources
/
Chat & Communication
/
Digsby build 37
/
digsby_setup.exe
/
lib
/
pyxmpp
/
jabber
/
vcard.pyo
(
.txt
)
< prev
Wrap
Python Compiled Bytecode
|
2008-10-13
|
36KB
|
1,264 lines
# Source Generated with Decompyle++
# File: in.pyo (Python 2.5)
__revision__ = '$Id: vcard.py 675 2007-06-28 08:36:17Z jajcus $'
__docformat__ = 'restructuredtext en'
import base64
import binascii
import libxml2
import re
import pyxmpp.jid as pyxmpp
from pyxmpp.utils import to_utf8, from_utf8
from pyxmpp.xmlextra import get_node_ns
from pyxmpp.objects import StanzaPayloadObject
from pyxmpp.exceptions import BadRequestProtocolError, JIDMalformedProtocolError, JIDError
VCARD_NS = 'vcard-temp'
class Empty(Exception):
pass
valid_string_re = re.compile('^[\\w\\d \\t]*$')
non_quoted_semicolon_re = re.compile('(?<!\\\\);')
def quote_semicolon(value):
return value.replace(';', '\\;')
def unquote_semicolon(value):
return value.replace('\\;', ';')
def rfc2425encode(name, value, parameters = None, charset = 'utf-8'):
if not parameters:
parameters = { }
if type(value) is unicode:
value = value.replace(u'\r\n', u'\\n')
value = value.replace(u'\n', u'\\n')
value = value.replace(u'\r', u'\\n')
value = value.encode(charset, 'replace')
elif type(value) is not str:
raise TypeError, 'Bad type for rfc2425 value'
elif not valid_string_re.match(value):
parameters['encoding'] = 'b'
value = binascii.b2a_base64(value)
ret = str(name).lower()
for k, v in parameters.items():
ret += ';%s=%s' % (str(k), str(v))
ret += ':'
while len(value) > 70:
ret += value[:70] + '\r\n '
value = value[70:]
ret += value + '\r\n'
return ret
class VCardField:
def __init__(self, name):
self.name = name
def __repr__(self):
return '<%s %r>' % (self.__class__, self.rfc2426())
def rfc2426(self):
return ''
class VCardString(VCardField):
def __init__(self, name, value, rfc2425parameters = None, empty_ok = False):
_unused = rfc2425parameters
VCardField.__init__(self, name)
if isinstance(value, libxml2.xmlNode):
value = value.getContent()
if value:
self.value = unicode(value, 'utf-8', 'replace').strip()
else:
self.value = u''
else:
self.value = value
if not (self.value) and not empty_ok:
raise Empty, 'Empty string value'
def rfc2426(self):
return rfc2425encode(self.name, self.value)
def as_xml(self, parent):
return parent.newTextChild(None, to_utf8(self.name.upper()), to_utf8(self.value))
def __unicode__(self):
return self.value
def __str__(self):
return self.value.encode('utf-8')
class VCardXString(VCardString):
def rfc2426(self):
return rfc2425encode('x-' + self.name, self.value)
class VCardJID(VCardField):
def __init__(self, name, value, rfc2425parameters = None):
_unused = rfc2425parameters
VCardField.__init__(self, name)
if isinstance(value, libxml2.xmlNode):
try:
self.value = pyxmpp.jid.JID(value.getContent())
except JIDError:
raise JIDMalformedProtocolError, 'JID malformed'
except:
None<EXCEPTION MATCH>JIDError
None<EXCEPTION MATCH>JIDError
self.value = pyxmpp.jid.JID(value)
if not self.value:
raise Empty, 'Empty JID value'
def rfc2426(self):
return rfc2425encode('x-jabberid', self.value.as_unicode())
def as_xml(self, parent):
name = to_utf8(self.name.upper())
content = self.value.as_utf8()
return parent.newTextChild(None, name, content)
def __unicode__(self):
return self.value.as_unicode()
def __str__(self):
return self.value.as_string()
class VCardName(VCardField):
def __init__(self, name, value, rfc2425parameters = None):
_unused = rfc2425parameters
VCardField.__init__(self, name)
if self.name.upper() != 'N':
raise RuntimeError, "VCardName handles only 'N' type"
if isinstance(value, libxml2.xmlNode):
(self.family, self.given, self.middle, self.prefix, self.suffix) = [
u''] * 5
empty = 1
n = value.children
vns = get_node_ns(value)
while n:
if n.type != 'element':
n = n.next
continue
ns = get_node_ns(n)
if ns and vns and ns.getContent() != vns.getContent():
n = n.next
continue
if n.name == 'FAMILY':
self.family = unicode(n.getContent(), 'utf-8')
empty = 0
if n.name == 'GIVEN':
self.given = unicode(n.getContent(), 'utf-8')
empty = 0
if n.name == 'MIDDLE':
self.middle = unicode(n.getContent(), 'utf-8')
empty = 0
if n.name == 'PREFIX':
self.prefix = unicode(n.getContent(), 'utf-8')
empty = 0
if n.name == 'SUFFIX':
self.suffix = unicode(n.getContent(), 'utf-8')
empty = 0
n = n.next
if empty:
raise Empty, 'Empty N value'
else:
v = non_quoted_semicolon_re.split(value)
value = [
u''] * 5
value[:len(v)] = v
(self.family, self.given, self.middle, self.prefix, self.suffix) = (lambda .0: for val in .0:
unquote_semicolon(val))(value)
def rfc2426(self):
return rfc2425encode('n', u';'.join((lambda .0: for val in .0:
quote_semicolon(val))((self.family, self.given, self.middle, self.prefix, self.suffix))))
def as_xml(self, parent):
n = parent.newChild(None, 'N', None)
n.newTextChild(None, 'FAMILY', to_utf8(self.family))
n.newTextChild(None, 'GIVEN', to_utf8(self.given))
n.newTextChild(None, 'MIDDLE', to_utf8(self.middle))
n.newTextChild(None, 'PREFIX', to_utf8(self.prefix))
n.newTextChild(None, 'SUFFIX', to_utf8(self.suffix))
return n
def __unicode__(self):
r = []
if self.prefix:
r.append(self.prefix.replace(u',', u' '))
if self.given:
r.append(self.given.replace(u',', u' '))
if self.middle:
r.append(self.middle.replace(u',', u' '))
if self.family:
r.append(self.family.replace(u',', u' '))
if self.suffix:
r.append(self.suffix.replace(u',', u' '))
return u' '.join(r)
def __str__(self):
return self.__unicode__().encode('utf-8')
class VCardImage(VCardField):
def __init__(self, name, value, rfc2425parameters = None):
VCardField.__init__(self, name)
if not rfc2425parameters:
rfc2425parameters = { }
(self.uri, self.type, self.image) = [
None] * 3
if isinstance(value, libxml2.xmlNode):
n = value.children
vns = get_node_ns(value)
while n:
if n.type != 'element':
n = n.next
continue
ns = get_node_ns(n)
if ns and vns and ns.getContent() != vns.getContent():
n = n.next
continue
if n.name == 'TYPE':
self.type = unicode(n.getContent(), 'utf-8', 'replace')
if n.name == 'BINVAL':
try:
self.image = base64.decodestring(n.getContent())
self.image = None
if n.name == 'EXTVAL':
self.uri = unicode(n.getContent(), 'utf-8', 'replace')
n = n.next
if self.uri and self.image:
raise ValueError, 'Bad %s value in vcard' % (name,)
if not (self.uri) and not (self.image):
raise Empty, 'Bad %s value in vcard' % (name,)
elif rfc2425parameters.get('value', '').lower() == 'uri':
self.uri = value
self.type = None
else:
self.type = rfc2425parameters.get('type')
self.image = value
def rfc2426(self):
if self.uri:
return rfc2425encode(self.name, self.uri, {
'value': 'uri' })
elif self.image:
if self.type:
p = {
'type': self.type }
else:
p = { }
return rfc2425encode(self.name, self.image, p)
def as_xml(self, parent):
n = parent.newChild(None, self.name.upper(), None)
if self.uri:
n.newTextChild(None, 'EXTVAL', to_utf8(self.uri))
elif self.type:
n.newTextChild(None, 'TYPE', self.type)
n.newTextChild(None, 'BINVAL', binascii.b2a_base64(self.image))
return n
def __unicode__(self):
if self.uri:
return self.uri
if self.type:
return u'(%s data)' % (self.type,)
return u'(binary data)'
def __str__(self):
return self.__unicode__().encode('utf-8')
class VCardAdr(VCardField):
def __init__(self, name, value, rfc2425parameters = None):
VCardField.__init__(self, name)
if not rfc2425parameters:
rfc2425parameters = { }
if self.name.upper() != 'ADR':
raise RuntimeError, "VCardAdr handles only 'ADR' type"
(self.pobox, self.extadr, self.street, self.locality, self.region, self.pcode, self.ctry) = [
''] * 7
self.type = []
if isinstance(value, libxml2.xmlNode):
self._VCardAdr__from_xml(value)
else:
t = rfc2425parameters.get('type')
if t:
self.type = t.split(',')
else:
self.type = [
'intl',
'postal',
'parcel',
'work']
v = non_quoted_semicolon_re.split(value)
value = [
''] * 7
value[:len(v)] = v
(self.pobox, self.extadr, self.street, self.locality, self.region, self.pcode, self.ctry) = (lambda .0: for val in .0:
unquote_semicolon(val))(value)
def __from_xml(self, value):
n = value.children
vns = get_node_ns(value)
while n:
if n.type != 'element':
n = n.next
continue
ns = get_node_ns(n)
if ns and vns and ns.getContent() != vns.getContent():
n = n.next
continue
if n.name == 'POBOX':
self.pobox = unicode(n.getContent(), 'utf-8', 'replace')
elif n.name in ('EXTADR', 'EXTADD'):
self.extadr = unicode(n.getContent(), 'utf-8', 'replace')
elif n.name == 'STREET':
self.street = unicode(n.getContent(), 'utf-8', 'replace')
elif n.name == 'LOCALITY':
self.locality = unicode(n.getContent(), 'utf-8', 'replace')
elif n.name == 'REGION':
self.region = unicode(n.getContent(), 'utf-8', 'replace')
elif n.name == 'PCODE':
self.pcode = unicode(n.getContent(), 'utf-8', 'replace')
elif n.name == 'CTRY':
self.ctry = unicode(n.getContent(), 'utf-8', 'replace')
elif n.name in ('HOME', 'WORK', 'POSTAL', 'PARCEL', 'DOM', 'INTL', 'PREF'):
self.type.append(n.name.lower())
n = n.next
if self.type == []:
self.type = [
'intl',
'postal',
'parcel',
'work']
elif 'dom' in self.type and 'intl' in self.type:
raise ValueError, "Both 'dom' and 'intl' specified in vcard ADR"
def rfc2426(self):
return rfc2425encode('adr', u';'.join((lambda .0: for val in .0:
quote_semicolon(val))((self.pobox, self.extadr, self.street, self.locality, self.region, self.pcode, self.ctry))), {
'type': ','.join(self.type) })
def as_xml(self, parent):
n = parent.newChild(None, 'ADR', None)
for t in ('home', 'work', 'postal', 'parcel', 'dom', 'intl', 'pref'):
if t in self.type:
n.newChild(None, t.upper(), None)
continue
n.newTextChild(None, 'POBOX', to_utf8(self.pobox))
n.newTextChild(None, 'EXTADD', to_utf8(self.extadr))
n.newTextChild(None, 'STREET', to_utf8(self.street))
n.newTextChild(None, 'LOCALITY', to_utf8(self.locality))
n.newTextChild(None, 'REGION', to_utf8(self.region))
n.newTextChild(None, 'PCODE', to_utf8(self.pcode))
n.newTextChild(None, 'CTRY', to_utf8(self.ctry))
return n
class VCardLabel(VCardField):
def __init__(self, name, value, rfc2425parameters = None):
VCardField.__init__(self, name)
if not rfc2425parameters:
rfc2425parameters = { }
if self.name.upper() != 'LABEL':
raise RuntimeError, "VCardAdr handles only 'LABEL' type"
if isinstance(value, libxml2.xmlNode):
self.lines = []
self.type = []
n = value.children
vns = get_node_ns(value)
while n:
if n.type != 'element':
n = n.next
continue
ns = get_node_ns(n)
if ns and vns and ns.getContent() != vns.getContent():
n = n.next
continue
if n.name == 'LINE':
l = unicode(n.getContent(), 'utf-8', 'replace').strip()
l = l.replace('\n', ' ').replace('\r', ' ')
self.lines.append(l)
elif n.name in ('HOME', 'WORK', 'POSTAL', 'PARCEL', 'DOM', 'INTL', 'PREF'):
self.type.append(n.name.lower())
n = n.next
if self.type == []:
self.type = [
'intl',
'postal',
'parcel',
'work']
elif 'dom' in self.type and 'intl' in self.type:
raise ValueError, "Both 'dom' and 'intl' specified in vcard LABEL"
if not self.lines:
self.lines = [
'']
else:
t = rfc2425parameters.get('type')
if t:
self.type = t.split(',')
else:
self.type = [
'intl',
'postal',
'parcel',
'work']
self.lines = value.split('\\n')
def rfc2426(self):
return rfc2425encode('label', u'\n'.join(self.lines), {
'type': ','.join(self.type) })
def as_xml(self, parent):
n = parent.newChild(None, 'ADR', None)
for t in ('home', 'work', 'postal', 'parcel', 'dom', 'intl', 'pref'):
if t in self.type:
n.newChild(None, t.upper(), None)
continue
for l in self.lines:
n.newTextChild(None, 'LINE', l)
return n
class VCardTel(VCardField):
def __init__(self, name, value, rfc2425parameters = None):
VCardField.__init__(self, name)
if not rfc2425parameters:
rfc2425parameters = { }
if self.name.upper() != 'TEL':
raise RuntimeError, "VCardTel handles only 'TEL' type"
if isinstance(value, libxml2.xmlNode):
self.number = None
self.type = []
n = value.children
vns = get_node_ns(value)
while n:
if n.type != 'element':
n = n.next
continue
ns = get_node_ns(n)
if ns and vns and ns.getContent() != vns.getContent():
n = n.next
continue
if n.name == 'NUMBER':
self.number = unicode(n.getContent(), 'utf-8', 'replace')
elif n.name in ('HOME', 'WORK', 'VOICE', 'FAX', 'PAGER', 'MSG', 'CELL', 'VIDEO', 'BBS', 'MODEM', 'ISDN', 'PCS', 'PREF'):
self.type.append(n.name.lower())
n = n.next
if self.type == []:
self.type = [
'voice']
if not self.number:
raise Empty, 'No tel number'
else:
t = rfc2425parameters.get('type')
if t:
self.type = t.split(',')
else:
self.type = [
'voice']
self.number = value
def rfc2426(self):
return rfc2425encode('tel', self.number, {
'type': ','.join(self.type) })
def as_xml(self, parent):
n = parent.newChild(None, 'TEL', None)
for t in ('home', 'work', 'voice', 'fax', 'pager', 'msg', 'cell', 'video', 'bbs', 'modem', 'isdn', 'pcs', 'pref'):
if t in self.type:
n.newChild(None, t.upper(), None)
continue
n.newTextChild(None, 'NUMBER', to_utf8(self.number))
return n
class VCardEmail(VCardField):
def __init__(self, name, value, rfc2425parameters = None):
VCardField.__init__(self, name)
if not rfc2425parameters:
rfc2425parameters = { }
if self.name.upper() != 'EMAIL':
raise RuntimeError, "VCardEmail handles only 'EMAIL' type"
if isinstance(value, libxml2.xmlNode):
self.address = None
self.type = []
n = value.children
vns = get_node_ns(value)
while n:
if n.type != 'element':
n = n.next
continue
ns = get_node_ns(n)
if ns and vns and ns.getContent() != vns.getContent():
n = n.next
continue
if n.name == 'USERID':
self.address = unicode(n.getContent(), 'utf-8', 'replace')
elif n.name in ('HOME', 'WORK', 'INTERNET', 'X400'):
self.type.append(n.name.lower())
n = n.next
if self.type == []:
self.type = [
'internet']
if not self.address:
raise Empty, 'No USERID'
else:
t = rfc2425parameters.get('type')
if t:
self.type = t.split(',')
else:
self.type = [
'internet']
self.address = value
def rfc2426(self):
return rfc2425encode('email', self.address, {
'type': ','.join(self.type) })
def as_xml(self, parent):
n = parent.newChild(None, 'EMAIL', None)
for t in ('home', 'work', 'internet', 'x400'):
if t in self.type:
n.newChild(None, t.upper(), None)
continue
n.newTextChild(None, 'USERID', to_utf8(self.address))
return n
class VCardGeo(VCardField):
def __init__(self, name, value, rfc2425parameters = None):
_unused = rfc2425parameters
VCardField.__init__(self, name)
if self.name.upper() != 'GEO':
raise RuntimeError, "VCardName handles only 'GEO' type"
if isinstance(value, libxml2.xmlNode):
(self.lat, self.lon) = [
None] * 2
n = value.children
vns = get_node_ns(value)
while n:
if n.type != 'element':
n = n.next
continue
ns = get_node_ns(n)
if ns and vns and ns.getContent() != vns.getContent():
n = n.next
continue
if n.name == 'LAT':
self.lat = unicode(n.getContent(), 'utf-8')
if n.name == 'LON':
self.lon = unicode(n.getContent(), 'utf-8')
n = n.next
if not (self.lat) or not (self.lon):
raise ValueError, 'Bad vcard GEO value'
else:
(self.lat, self.lon) = (lambda .0: for val in .0:
unquote_semicolon(val))(non_quoted_semicolon_re.split(value))
def rfc2426(self):
return rfc2425encode('geo', u';'.join((lambda .0: for val in .0:
quote_semicolon(val))((self.lat, self.lon))))
def as_xml(self, parent):
n = parent.newChild(None, 'GEO', None)
n.newTextChild(None, 'LAT', to_utf8(self.lat))
n.newTextChild(None, 'LON', to_utf8(self.lon))
return n
class VCardOrg(VCardField):
def __init__(self, name, value, rfc2425parameters = None):
_unused = rfc2425parameters
VCardField.__init__(self, name)
if self.name.upper() != 'ORG':
raise RuntimeError, "VCardName handles only 'ORG' type"
if isinstance(value, libxml2.xmlNode):
(self.name, self.unit) = (None, '')
n = value.children
vns = get_node_ns(value)
while n:
if n.type != 'element':
n = n.next
continue
ns = get_node_ns(n)
if ns and vns and ns.getContent() != vns.getContent():
n = n.next
continue
if n.name == 'ORGNAME':
self.name = unicode(n.getContent(), 'utf-8')
if n.name == 'ORGUNIT':
self.unit = unicode(n.getContent(), 'utf-8')
n = n.next
if not self.name:
raise Empty, 'Bad vcard ORG value'
else:
sp = non_quoted_semicolon_re.split(value, 1)
if len(sp) > 1:
(self.name, self.unit) = (lambda .0: for val in .0:
unquote_semicolon(val))(sp)
else:
self.name = unquote_semicolon(sp[0])
self.unit = None
def rfc2426(self):
if self.unit:
return rfc2425encode('org', u';'.join((lambda .0: for val in .0:
quote_semicolon(val))((self.name, self.unit))))
else:
return rfc2425encode('org', unicode(quote_semicolon(self.name)))
def as_xml(self, parent):
n = parent.newChild(None, 'ORG', None)
n.newTextChild(None, 'ORGNAME', to_utf8(self.name))
n.newTextChild(None, 'ORGUNIT', to_utf8(self.unit))
return n
class VCardCategories(VCardField):
def __init__(self, name, value, rfc2425parameters = None):
_unused = rfc2425parameters
VCardField.__init__(self, name)
self.name = name
if self.name.upper() != 'CATEGORIES':
raise RuntimeError, "VCardName handles only 'CATEGORIES' type"
if isinstance(value, libxml2.xmlNode):
self.keywords = []
n = value.children
vns = get_node_ns(value)
while n:
if n.type != 'element':
n = n.next
continue
ns = get_node_ns(n)
if ns and vns and ns.getContent() != vns.getContent():
n = n.next
continue
if n.name == 'KEYWORD':
self.keywords.append(unicode(n.getContent(), 'utf-8'))
n = n.next
if not self.keywords:
raise Empty, 'Bad vcard CATEGORIES value'
else:
self.keywords = value.split(',')
def rfc2426(self):
return rfc2425encode('keywords', u','.join(self.keywords))
def as_xml(self, parent):
n = parent.newChild(None, 'CATEGORIES', None)
for k in self.keywords:
n.newTextChild(None, 'KEYWORD', to_utf8(k))
return n
class VCardSound(VCardField):
def __init__(self, name, value, rfc2425parameters = None):
VCardField.__init__(self, name)
if not rfc2425parameters:
rfc2425parameters = { }
(self.uri, self.sound, self.phonetic) = [
None] * 3
if isinstance(value, libxml2.xmlNode):
n = value.children
vns = get_node_ns(value)
while n:
if n.type != 'element':
n = n.next
continue
ns = get_node_ns(n)
if ns and vns and ns.getContent() != vns.getContent():
n = n.next
continue
if n.name == 'BINVAL':
if self.phonetic or self.uri:
raise ValueError, 'Bad SOUND value in vcard'
self.sound = base64.decodestring(n.getContent())
if n.name == 'PHONETIC':
if self.sound or self.uri:
raise ValueError, 'Bad SOUND value in vcard'
self.phonetic = unicode(n.getContent(), 'utf-8', 'replace')
if n.name == 'EXTVAL':
if self.phonetic or self.sound:
raise ValueError, 'Bad SOUND value in vcard'
self.uri = unicode(n.getContent(), 'utf-8', 'replace')
n = n.next
if not (self.phonetic) and not (self.uri) and not (self.sound):
raise Empty, 'Bad SOUND value in vcard'
elif rfc2425parameters.get('value', '').lower() == 'uri':
self.uri = value
self.sound = None
self.phonetic = None
else:
self.sound = value
self.uri = None
self.phonetic = None
def rfc2426(self):
if self.uri:
return rfc2425encode(self.name, self.uri, {
'value': 'uri' })
elif self.sound:
return rfc2425encode(self.name, self.sound)
def as_xml(self, parent):
n = parent.newChild(None, self.name.upper(), None)
if self.uri:
n.newTextChild(None, 'EXTVAL', to_utf8(self.uri))
elif self.phonetic:
n.newTextChild(None, 'PHONETIC', to_utf8(self.phonetic))
else:
n.newTextChild(None, 'BINVAL', binascii.b2a_base64(self.sound))
return n
class VCardPrivacy(VCardField):
def __init__(self, name, value, rfc2425parameters = None):
_unused = rfc2425parameters
VCardField.__init__(self, name)
if isinstance(value, libxml2.xmlNode):
self.value = None
n = value.children
vns = get_node_ns(value)
while n:
if n.type != 'element':
n = n.next
continue
ns = get_node_ns(n)
if ns and vns and ns.getContent() != vns.getContent():
n = n.next
continue
if n.name == 'PUBLIC':
self.value = 'public'
elif n.name == 'PRIVATE':
self.value = 'private'
elif n.name == 'CONFIDENTAL':
self.value = 'confidental'
n = n.next
if not self.value:
raise Empty
else:
self.value = value
def rfc2426(self):
return rfc2425encode(self.name, self.value)
def as_xml(self, parent):
if self.value in ('public', 'private', 'confidental'):
n = parent.newChild(None, self.name.upper(), None)
n.newChild(None, self.value.upper(), None)
return n
class VCardKey(VCardField):
def __init__(self, name, value, rfc2425parameters = None):
VCardField.__init__(self, name)
if not rfc2425parameters:
rfc2425parameters = { }
if isinstance(value, libxml2.xmlNode):
(self.type, self.cred) = (None, None)
n = value.children
vns = get_node_ns(value)
while n:
if n.type != 'element':
n = n.next
continue
ns = get_node_ns(n)
if ns and vns and ns.getContent() != vns.getContent():
n = n.next
continue
if n.name == 'TYPE':
self.type = unicode(n.getContent(), 'utf-8', 'replace')
if n.name == 'CRED':
self.cred = base64.decodestring(n.getContent())
n = n.next
if not self.cred:
raise Empty, 'Bad %s value in vcard' % (name,)
else:
self.type = rfc2425parameters.get('type')
self.cred = value
def rfc2426(self):
if self.type:
p = {
'type': self.type }
else:
p = { }
return rfc2425encode(self.name, self.cred, p)
def as_xml(self, parent):
n = parent.newChild(None, self.name.upper(), None)
if self.type:
n.newTextChild(None, 'TYPE', self.type)
n.newTextChild(None, 'CRED', binascii.b2a_base64(self.cred))
return n
class VCard(StanzaPayloadObject):
xml_element_name = 'vCard'
xml_element_namespace = VCARD_NS
components = {
'FN': (VCardString, 'required'),
'N': (VCardName, 'required'),
'NICKNAME': (VCardString, 'multi'),
'PHOTO': (VCardImage, 'multi'),
'BDAY': (VCardString, 'multi'),
'ADR': (VCardAdr, 'multi'),
'LABEL': (VCardLabel, 'multi'),
'TEL': (VCardTel, 'multi'),
'EMAIL': (VCardEmail, 'multi'),
'JABBERID': (VCardJID, 'multi'),
'MAILER': (VCardString, 'multi'),
'TZ': (VCardString, 'multi'),
'GEO': (VCardGeo, 'multi'),
'TITLE': (VCardString, 'multi'),
'ROLE': (VCardString, 'multi'),
'LOGO': (VCardImage, 'multi'),
'AGENT': ('VCardAgent', 'ignore'),
'ORG': (VCardOrg, 'multi'),
'CATEGORIES': (VCardCategories, 'multi'),
'NOTE': (VCardString, 'multi'),
'PRODID': (VCardString, 'multi'),
'REV': (VCardString, 'multi'),
'SORT-STRING': (VCardString, 'multi'),
'SOUND': (VCardSound, 'multi'),
'UID': (VCardString, 'multi'),
'URL': (VCardString, 'multi'),
'CLASS': (VCardString, 'multi'),
'KEY': (VCardKey, 'multi'),
'DESC': (VCardXString, 'multi') }
def __init__(self, data):
self.n = None
del self.n
self.content = { }
if isinstance(data, libxml2.xmlNode):
self._VCard__from_xml(data)
else:
self._VCard__from_rfc2426(data)
if not self.content.get('N') and self.content.get('FN'):
s = self.content['FN'].value.replace(';', ',')
s = s.split(None, 2)
if len(s) == 2:
s = u'%s;%s;;;' % (s[1], s[0])
elif len(s) == 3:
s = u'%s;%s;%s' % (s[2], s[0], s[1])
else:
s = u'%s;;;;' % (s[0],)
self.content['N'] = VCardName('N', s)
elif not self.content.get('FN') and self.content.get('N'):
self._VCard__make_fn()
for _unused, tp in self.components.items():
if self.content.has_key(c):
continue
if tp == 'required':
raise ValueError, '%s is missing' % (c,)
continue
if tp == 'multi':
self.content[c] = []
continue
if tp == 'optional':
self.content[c] = None
continue
continue
def __make_fn(self):
s = []
if self.n.prefix:
s.append(self.n.prefix)
if self.n.given:
s.append(self.n.given)
if self.n.middle:
s.append(self.n.middle)
if self.n.family:
s.append(self.n.family)
if self.n.suffix:
s.append(self.n.suffix)
s = u' '.join(s)
self.content['FN'] = VCardString('FN', s, empty_ok = True)
def __from_xml(self, data):
ns = get_node_ns(data)
if ns and ns.getContent() != VCARD_NS:
raise ValueError, 'Not in the %r namespace' % (VCARD_NS,)
if data.name.lower() != 'vCard'.lower():
raise ValueError, 'Bad root element name: %r' % (data.name,)
n = data.children
dns = get_node_ns(data)
while n:
if n.type != 'element':
n = n.next
continue
ns = get_node_ns(n)
if ns and dns and ns.getContent() != dns.getContent():
n = n.next
continue
if not self.components.has_key(n.name):
n = n.next
continue
(cl, tp) = self.components[n.name]
if tp in ('required', 'optional'):
if self.content.has_key(n.name):
raise ValueError, 'Duplicate %s' % (n.name,)
try:
self.content[n.name] = cl(n.name, n)
except Empty:
pass
except:
None<EXCEPTION MATCH>Empty
None<EXCEPTION MATCH>Empty
if tp == 'multi':
if not self.content.has_key(n.name):
self.content[n.name] = []
try:
self.content[n.name].append(cl(n.name, n))
except Empty:
pass
except:
None<EXCEPTION MATCH>Empty
None<EXCEPTION MATCH>Empty
n = n.next
def __from_rfc2426(self, data):
data = from_utf8(data)
lines = data.split('\n')
started = 0
current = None
for l in lines:
if not l:
continue
if l[-1] == '\r':
l = l[:-1]
if not l:
continue
if l[0] in ' \t':
if current is None:
continue
current += l[1:]
continue
if not started and current and current.upper().strip() == 'BEGIN:VCARD':
started = 1
elif started and current.upper().strip() == 'END:VCARD':
current = None
break
elif current and started:
self._process_rfc2425_record(current)
current = l
if started and current:
self._process_rfc2425_record(current)
def _process_rfc2425_record(self, data):
(label, value) = data.split(':', 1)
value = value.replace('\\n', '\n').replace('\\N', '\n')
psplit = label.lower().split(';')
name = psplit[0]
params = psplit[1:]
if u'.' in name:
name = name.split('.', 1)[1]
name = name.upper()
if name in (u'X-DESC', u'X-JABBERID'):
name = name[2:]
if not self.components.has_key(name):
return None
(cl, tp) = self.components[name]
if tp in ('required', 'optional'):
if self.content.has_key(name):
raise ValueError, 'Duplicate %s' % (name,)
try:
self.content[name] = cl(name, value, params)
except Empty:
pass
except:
None<EXCEPTION MATCH>Empty
None<EXCEPTION MATCH>Empty
if tp == 'multi':
if not self.content.has_key(name):
self.content[name] = []
try:
self.content[name].append(cl(name, value, params))
except Empty:
pass
except:
None<EXCEPTION MATCH>Empty
None<EXCEPTION MATCH>Empty
return None
def __repr__(self):
return '<vCard of %r>' % (self.content['FN'].value,)
def rfc2426(self):
ret = 'begin:VCARD\r\n'
ret += 'version:3.0\r\n'
for _unused, value in self.content.items():
if value is None:
continue
if type(value) is list:
for v in value:
ret += v.rfc2426()
v = value.rfc2426()
ret += v
return ret + 'end:VCARD\r\n'
def complete_xml_element(self, xmlnode, _unused):
for _unused1, value in self.content.items():
if value is None:
continue
if type(value) is list:
for v in value:
v.as_xml(xmlnode)
value.as_xml(xmlnode)
def __getattr__(self, name):
try:
return self.content[name.upper().replace('_', '-')]
except KeyError:
raise AttributeError, 'Attribute %r not found' % (name,)
def __getitem__(self, name):
return self.content[name.upper()]